package org.cupk2.base.jwt;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.cupk2.tools.config.Cupk2ConfigEnum;
import org.cupk2.tools.config.Cupk2ConfigUtils;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.Map;

@Slf4j
public class CupkJwtUtils {
    public static SecretKey skey = null;
    public static String skeyText = new Cupk2ConfigUtils(Cupk2ConfigEnum.CUPK2_PROPERTIES).getData("cupk2.conf.jwt.secret.key");
    public static Boolean KEY_TYPE_RANDOM = new Cupk2ConfigUtils(Cupk2ConfigEnum.CUPK2_PROPERTIES).getData("cupk2.conf.jwt.secret.key").equals("RANDOM");
    /**是否使用随机密钥
     * @param keyTypeRandom
     */
    public static void setKeyTypeRandom(Boolean keyTypeRandom) {
        KEY_TYPE_RANDOM = keyTypeRandom;
    }

    private static SecretKey getSecretKey() {
        if (skey == null) {
            if (KEY_TYPE_RANDOM) {
                skey = Jwts.SIG.HS256.key().build();
            } else {
                skey = Keys.hmacShaKeyFor(skeyText.getBytes(StandardCharsets.UTF_8));
            }
        }
        return skey;
    }

    /**
     * 生成jwt
     * 使用Hs256算法
     *
     * @param ttlMillis jwt过期时间(毫秒)
     * @param claims    设置的信息
     * @return
     */
    public static String createJwt(long ttlMillis, Map<String, Object> claims) {

        long expMillis = System.currentTimeMillis() + ttlMillis;
        Date exp = new Date(expMillis);


        JwtBuilder builder = Jwts.builder()

                .signWith(getSecretKey())

                .claims(claims)

                .expiration(exp);
        return builder.compact();
    }

    /**
     * Token解密
     *
     * @param token 加密后的token
     * @return
     */
    public static CupkJwtClaims parseJWT(String token) {
        Claims claims = null;
        try {


        JwtParser jwtParser = Jwts.parser()

                .verifyWith(getSecretKey()).build();
        Jws<Claims> jws = jwtParser.parseSignedClaims(token);
            claims = jws.getPayload();
        } catch (Exception e) {

            log.error(e.getMessage(), e);
            return null;
        }
        return new CupkJwtClaims(claims);
    }

    /**
     * 获取jwt剩余有效时间
     *
     * @param token jwt字符串
     * @return 剩余有效时间(毫秒), 如果token已过期, 返回负值
     */
    public static long getJwtRemainingTime(String token) {
        CupkJwtClaims claims = parseJWT(token);
        Date expiration = claims.getExpiration();
        long currentTimeMillis = System.currentTimeMillis();
        return (expiration.getTime() - currentTimeMillis)/1000;
    }

    public static String createRefreshJwt(Map<String, Object> claims) {
        claims.put(CupkJwtConfig.ClaimsKey.TYPE.getKey(), "2");
        return createJwt(CupkJwtConfig.getRefreshTtlMillis(), claims);
    }

    public static String createAuthJwt(Map<String, Object> claims) {
        claims.put(CupkJwtConfig.ClaimsKey.TYPE.getKey(), "1");
        return createJwt(CupkJwtConfig.getAuthTtlMillis(), claims);
    }
}


